import * as THREE from 'three';

let glitterParticles: THREE.Points | null = null;
let glitterTexture: THREE.CanvasTexture | null = null;
let currentWorker: Worker | null = null;
let isLargeGlitter = false;
let cachedMesh: THREE.Mesh | null = null;

// 新增：缓存首次计算的尺寸参数（关键！避免重复计算导致的误差）
let cachedSurfaceArea: number | null = null;
let cachedBaseSize: number | null = null;

// 创建闪光纹理（不变）
function createGlitterTexture() {
    if (glitterTexture) return glitterTexture;
    
    const canvas = document.createElement('canvas');
    canvas.width = 32;
    canvas.height = 32;
    const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
    
    for (let i = 0; i < 80; i++) {
        const size = Math.random() * 3 + 1;
        const x = Math.random() * 32;
        const y = Math.random() * 32;
        
        const gradient = ctx.createRadialGradient(x, y, 0, x, y, size * 1.5);
        gradient.addColorStop(0, `rgba(255, 240, 100, ${Math.random() * 0.8 + 0.2})`);
        gradient.addColorStop(1, `rgba(218, 165, 32, ${Math.random() * 0.4 + 0.1})`);
        
        ctx.fillStyle = gradient;
        ctx.beginPath();
        ctx.arc(x, y, size, 0, Math.PI * 2);
        ctx.fill();
    }
    
    glitterTexture = new THREE.CanvasTexture(canvas);
    glitterTexture.needsUpdate = true;
    return glitterTexture;
}

// 切换函数（无需传mesh）
export function toggleGlitterSize() {
    if (!cachedMesh || cachedSurfaceArea === null || cachedBaseSize === null) {
        console.error('请先调用addGlitterToCase(mesh)添加粒子');
        return isLargeGlitter;
    }
    
    isLargeGlitter = !isLargeGlitter;
    console.log(`切换到${isLargeGlitter ? '大粉粒' : '小粉粒'}模式`);
    addGlitterToCase();
    return isLargeGlitter;
}

// 主函数：使用缓存的初始尺寸参数，避免重复计算误差
export function addGlitterToCase(mesh?: THREE.Mesh) {
    // 首次调用必须传入mesh，并缓存初始尺寸参数
    if (!cachedMesh && !mesh) {
        console.error('首次调用必须传入mesh！');
        return;
    }
    if (mesh) {
        cachedMesh = mesh;
        // 首次计算并缓存尺寸参数（只算一次，后续复用）
        const phoneCaseBox = new THREE.Box3().setFromObject(mesh);
        const phoneCaseWidth = phoneCaseBox.max.x - phoneCaseBox.min.x;
        const phoneCaseHeight = phoneCaseBox.max.y - phoneCaseBox.min.y;
        cachedBaseSize = Math.min(phoneCaseWidth, phoneCaseHeight);
        cachedSurfaceArea = phoneCaseWidth * phoneCaseHeight;
        console.log('已缓存初始尺寸参数：', {
            surfaceArea: cachedSurfaceArea,
            baseSize: cachedBaseSize
        });
    }
    // 确保缓存有效
    if (!cachedMesh || cachedSurfaceArea === null || cachedBaseSize === null) return;

    // 清理旧粒子（不变）
    if (glitterParticles) {
        if (glitterParticles.parent) glitterParticles.parent.remove(glitterParticles);
        (glitterParticles.material as THREE.ShaderMaterial).dispose();
        glitterParticles.geometry.dispose();
        glitterParticles = null;
    }
    if (currentWorker) {
        currentWorker.terminate();
        currentWorker = null;
    }

    // 【关键修复：使用缓存的初始尺寸参数，而非每次重新计算】
    const surfaceArea = cachedSurfaceArea;
    const baseSize = cachedBaseSize;
    
    // 基于初始尺寸计算粒子参数（确保切换时数量稳定）
    const { particleCount, glitterBaseScale } = isLargeGlitter 
        ? { 
            particleCount: Math.floor(surfaceArea * 10), // 大粉粒数量（基于初始面积）
            glitterBaseScale: baseSize * 0.004
          } 
        : { 
            particleCount: Math.floor(surfaceArea * 15), // 小粉粒数量（基于初始面积）
            glitterBaseScale: baseSize * 0.002
          };
    
    console.log(`当前模式参数：数量=${particleCount}，基础大小=${glitterBaseScale}`);
    if (particleCount < 100) return;

    const minGlitterSize = glitterBaseScale * 0.5;
    const maxGlitterSize = glitterBaseScale * 1.2;

    // 提取模型数据（仍使用当前mesh的几何体，仅尺寸参数用缓存）
    const geometry = cachedMesh.geometry;
    const positions = geometry.attributes.position.array;
    const indices = geometry.index?.array || null;

    // 创建Worker（不变）
    currentWorker = new Worker(new URL('./glitter-worker.ts', import.meta.url), {
        type: 'module'
    });

    currentWorker.postMessage({
        positions: positions,
        indices: indices,
        count: particleCount,
        minGlitterSize,
        maxGlitterSize,
    });

    currentWorker.onmessage = (e) => {
        if (e.data.error) {
            console.error('金粉计算错误：', e.data.error);
            return;
        }

        const { positions: particlePositions, sizes: particleSizes } = e.data;
        console.log(`新粒子生成：数量=${particlePositions.length / 3}，大小范围=[${Math.min(...particleSizes)}, ${Math.max(...particleSizes)}]`);
        
        if (!particlePositions.length) return;

        // 创建几何体和材质（不变）
        const geometry = new THREE.BufferGeometry();
        geometry.setAttribute(
            'position',
            new THREE.Float32BufferAttribute(new Float32Array(particlePositions), 3)
        );
        geometry.setAttribute(
            'size',
            new THREE.Float32BufferAttribute(new Float32Array(particleSizes), 1)
        );

        const randomOffsets = new Float32Array(particlePositions.length / 3);
        for (let i = 0; i < randomOffsets.length; i++) {
            randomOffsets[i] = Math.random();
        }
        geometry.setAttribute(
            'randomOffset',
            new THREE.Float32BufferAttribute(randomOffsets, 1)
        );

        const material = new THREE.ShaderMaterial({
            uniforms: {
                baseColor: { value: new THREE.Color('#ffffff') },
                specularColor: { value: new THREE.Color(0xffe87c) },
                lightDir: { value: new THREE.Vector3(25, 20, -15).normalize() },
                map: { value: createGlitterTexture() },
                time: { value: 0 },
                emissiveColor: { value: new THREE.Color('#ffffff') }, // 调整发光颜色
                emissiveBaseIntensity: { value: 1 },
                emissiveBoostIntensity: { value: 1.5 },
            },
            vertexShader: `
                attribute float size;
                attribute float randomOffset;
                uniform float time;
                uniform vec3 lightDir;
                varying vec3 vNormal;
                varying vec3 vViewDir;
                varying float vRandom;
                
                void main() {
                    vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
                    gl_Position = projectionMatrix * mvPosition;
                    
                    float pulse = sin(time * 0.8) * 0.2 + 1.2;
                    gl_PointSize = size * pulse * (250.0 / -mvPosition.z);
                    
                    vNormal = normalize(position);
                    vViewDir = normalize(-mvPosition.xyz);
                    vRandom = randomOffset;
                }
            `,
            fragmentShader: `
            uniform vec3 baseColor;
            uniform vec3 specularColor;
            uniform vec3 lightDir;
            uniform vec3 emissiveColor;
            uniform float time;
            uniform sampler2D map;
            varying vec3 vNormal;
            varying vec3 vViewDir;
            varying float vRandom;
            
            void main() {
                vec4 tex = texture2D(map, gl_PointCoord);
                if (tex.a < 0.25) discard;
                
                vec3 diffuse = baseColor * 1.2 * tex.rgb;
                diffuse = mix(diffuse, vec3(dot(diffuse, vec3(0.299, 0.587, 0.114))), -0.3);
                
                vec3 halfDir = normalize(lightDir + vViewDir);
                float angleOffset = (vRandom - 0.5) * 0.3;
                float dotProd = dot(vNormal, halfDir) + angleOffset;
                float aligned = max(dotProd, 0.0);
                float spec = pow(aligned, 80.0);
                float flicker = sin(time * 5.0 + vRandom * 10.0) * 0.2 + 0.8;
                vec3 specular = specularColor * spec * flicker * 10.0;
                
                vec3 emissive = emissiveColor * 0.6 * tex.a;
                
                gl_FragColor = vec4(diffuse + emissive + specular, tex.a * 0.95);
            }
        `,
            transparent: true,
            blending: THREE.AdditiveBlending,
            depthWrite: true
        });

        // 添加新粒子
        glitterParticles = new THREE.Points(geometry, material);
        glitterParticles.visible = true;
        cachedMesh.add(glitterParticles);
        console.log('新粒子已添加到模型');

        // 重置动画时间
        (glitterParticles.material as THREE.ShaderMaterial).uniforms.time.value = 0;

        // 启动动画
        if (!window['glitterAnimation']) {
            window['glitterAnimation'] = true;
            function loop() {
                if (glitterParticles && window['glitterAnimation']) {
                    (glitterParticles.material as THREE.ShaderMaterial).uniforms.time.value += 0.01;
                }
                requestAnimationFrame(loop);
            }
            loop();
        }
    };

    currentWorker.onerror = (error) => {
        console.error('Worker错误：', error);
        currentWorker = null;
    };
}

// 清理函数（同时清空缓存）
export function disposeGlitter() {
    if (glitterParticles) {
        (glitterParticles.material as THREE.ShaderMaterial).dispose();
        glitterParticles.geometry.dispose();
        glitterParticles = null;
    }
    if (glitterTexture) {
        glitterTexture.dispose();
        glitterTexture = null;
    }
    if (currentWorker) {
        currentWorker.terminate();
        currentWorker = null;
    }
    // 清空所有缓存
    cachedMesh = null;
    cachedSurfaceArea = null;
    cachedBaseSize = null;
    window['glitterAnimation'] = false;
}
